TOOL.Category    = "Conna's Tools"
TOOL.Name        = "#Private Space Tool"
TOOL.Command     = nil
TOOL.ConfigName  = ""

// ConVars

TOOL.ClientConVar["Width"] = "1024"
TOOL.ClientConVar["Height"] = "1024"

// Register

cleanup.Register("privatespaces")

// ConVars

CreateConVar("sbox_maxprivatespaces", 1, FCVAR_NOTIFY)

// Client

if (CLIENT) then
	// Tool
	
	language.Add("Tool_privatespace_name", "Private Space Tool")
	language.Add("Tool_privatespace_desc", "Create a private space where nobody can enter")
	language.Add("Tool_privatespace_0", "Left click to spawn a Private Space")
	
	// Other
	
	language.Add("Undone_privatespace", "Undone Private Space")
	language.Add("SBoxLimit_privatespaces", "You've hit the Private Spaces limit!")
	language.Add("Cleanup_privatespaces", "Private Spaces")
	language.Add("Cleaned_privatespaces", "Cleaned up all Private Spaces")
end

// Message

function TOOL:Message(Text)
	if (SERVER) then
		self:GetOwner():SendLua("GAMEMODE:AddNotify('"..Text.."', NOTIFY_GENERIC, 10)")
		self:GetOwner():SendLua("surface.PlaySound('ambient/water/drip"..math.random(1, 4)..".wav')")
	end
end

// Left click

function TOOL:LeftClick(Trace)
	if(CLIENT) then
		return true
	end
	
	// Locals
	
	local Player = self:GetOwner()
	local Width = self:GetClientNumber("Width")
	local Height = self:GetClientNumber("Height")
	
	// Keep it nice and whole
	
	Width = math.Clamp(Width, 1, 1024)
	Height = math.Clamp(Height, 1, 1024)
	
	// Check for entities nearby
	
	local Entities = ents.FindInSphere(Trace.HitPos, Width)
	
	if (#Entities != 0) then
		self:Message("You cannot spawn a private area with entities nearby!")
		
		return false
	end
	
	// Spawn angles
	
	local Ang = Trace.HitNormal:Angle()
	
	Ang.pitch = Ang.pitch + 90
	
	// Spawn it

	local Space = CreatePrivateSpace(Player, Ang, Trace.HitPos, Width, Height)
	
	if not (Space) then return false end
	
	// Position
	
	local Minimum = Space:OBBMins()
	
	Space:SetPos(Trace.HitPos - Trace.HitNormal * Minimum.z)
	
	// Undo
	
	undo.Create("privatespace")
		undo.AddEntity(Space)
		undo.SetPlayer(Player)
	undo.Finish()
	
	// Add count
	
	Player:AddCount("privatespaces", Space)
	
	Player:AddCleanup("privatespaces", Space)
	
	// Message
	
	self:Message("Private Space has been created!")
	
	return true, Space
end

// Make it

if (SERVER) then
	function CreatePrivateSpace(Player, Ang, Pos, Width, Height, Nocollide, Vel, Avel, Frozen)
		if (!Player:CheckLimit("privatespaces")) then return false end
		
		local Space = ents.Create("gmod_privatespace")
		
		Space:SetModel("models/props/de_dust/du_privatespace_64x64.mdl")
		Space:SetAngles(Ang)
		Space:SetPos(Pos)
		Space:Spawn()
		Space:Activate()
	
		// Other
		
		Space:SetDimensions(Width, Height)
		Space:UpdateEntityLabel()
		Space:SetPlayer(Player)
		
		// Merge
		
		local Table = {
			Width = Width,
			Height = Height
		}
		
		table.Merge(Space, Table)
		
		// Frozen and nocollide
		
		if (Frozen) then Space:GetPhysicsObject():EnableMotion(false) end
		
		if (Nocollide) then Space:GetPhysicsObject():EnableCollisions(false) end
		
		return Space
	end
	
	duplicator.RegisterEntityClass("gmod_privatespace", CreatePrivateSpace, "Ang", "Pos", "Width", "Height", "Nocollide", "Vel", "Avel", "Frozen")
end

// Control panel

function TOOL.BuildCPanel(Panel)
	Panel:AddControl("Header", {Text = "#Tool_privatespace_name", Description = "#Tool_privatespace_desc"})
	
	Panel:AddControl("Slider", {Label = "Width", Type = "Integer", Min = 1, Max = 1024, Command = "privatespace_Width"})
	
	Panel:AddControl("Slider", {Label = "Height", Type = "Integer", Min = 1, Max = 1024, Command = "privatespace_Height"})
end